
import unittest

import helper.person as person

# ========================================================== #
# whether "writelines" or "write", we have to add "\n" manually ourself
# ========================================================== #
def output_writelines(fw,lines):
    seperated_lines = (x+"\n" for x in lines)
    fw.writelines(seperated_lines)
    
def output_write(fw,lines):
    for line in lines:
        fw.write(line+"\n")
        
# ========================================================== #
# read operations:
# 1. using file object as an iterator, save memory
# 2. readlines read all lines into a list, avoid occupying file for too much long time
# both methods, we have to remove line separators ourself
# ========================================================== #
def input_iter_file(fr):
    readlines = []
    for line in fr:
        readlines.append(line.strip())
    return readlines

def input_readlines(fr):
    raw_lines = fr.readlines() 
    return [x.strip() for x in raw_lines]        

# ========================================================== #
# check
# ========================================================== #   
class TestTextFile(unittest.TestCase):
    
    def check_text_io(self,write_action,read_function):
        filename = "data/test_text_io.txt"
        
        srclines = ["Hello WSU from cheka in Python","Hello Python from WSU"]
        
        # ------------------------------ write
        write_handler = open(filename,"wt")
        try:
            write_action(write_handler,srclines)
        finally:
            write_handler.close()
            
        # ------------------------------ read
        read_handler = open(filename,"rt")
        
        try:
            cpylines = read_function(read_handler)
        finally:
            read_handler.close()
            
        # ------------------------------ check
        self.assertEqual(srclines,cpylines)
        
    def test_text_io(self):
        for write_action in [output_write,output_writelines]:
            for read_function in [input_iter_file,input_readlines]:
                self.check_text_io(write_action,read_function)
            
        

class TestBinaryFile(unittest.TestCase):
    """
    in python, binary IO and text IO don't differ that much, as in C#
    (in C#, stream IO is for binary, while some adapter is for text)
    both IO can use "read" and "write"
    (maybe that is because in python, byte[] is also represented as string)
    """
    
    def test_write_read(self):
        aperson = person.Person(100,"cheka")
        
        filename = "data/test_binary_io.dat"
        
        # ------------------- write
        wbinimage = person.StructPackSerializer.serialize(aperson) 
        
        fw = open(filename,"wb")
        try:
            fw.write(wbinimage)
        finally:
            fw.close()
            
        # ------------------- read
        fr = open(filename,"rb")
        
        try:
            rbinimage = fr.read()
        finally:
            fr.close()
            
        cpy_person = person.StructPackSerializer.deserialize(rbinimage)
        
        # ------------------- cheka
        self.assertTrue(aperson is not cpy_person)
        self.assertEqual(aperson,cpy_person)
        
        
        
if __name__ == "__main__":
    unittest.main()
        